var id;
var room;
var configuration = {
    "iceServers": [{urls: "stun:stun.l.google.com:19302"}]
};
var wsUrl = "ws://localhost:8888/ws";
function login() {
    const request = JSON.stringify({
        action: "connect",
        userId: id
    });
    console.log(request);
    socket.send(request);
}
function logout() {
    const request =
        JSON.stringify({
            action: "disConnect",
            userId: id
        });
    console.log(request);
    socket.send(request);
}
/**
    * MAIN_PARAMETER:
    *     Boolean audio : 是否发送音频
    *     Boolean video : 是否发送视频
    *     Integer pin : 密码
    *     Integer substream : substream（0-2）：数字越大分辨率越高
    *     Integer temporal : temporal（0-2）：数字越大帧率越高
    *     Integer spatial_layer :  <spatial layer to receive (0-1), in case VP9-SVC is enabled; optional>,
    *     Integer temporal_layer : <temporal layers to receive (0-2), in case VP9-SVC is enabled; optional>
    *     Integer bitrate : 最大码率,不设置着为无上限
    *     Boolean restart : 重新协商offer
    *     boolean keyframe :  <true|false, whether we should send this publisher a keyframe request>
    *     boolean record :  <true|false, whether this publisher should be recorded or not; optional>,
    *     String filename :  <if recording, the base path/file to use for the recording files; optional>",
    *     String display : <new display name to use in the room; optional>",
    *     String audio_active_packets : <new audio_active_packets to overwrite in the room one; optional>",
    *     String audio_level_average : <new audio_level_average to overwrite the room one; optional>",
    *     Integer mid : <mid of the m-line to refer to for this configure request; optional>,
    *     Boolean send : <true|false, depending on whether the media addressed by the above mid should be relayed or not; optional>,
    * EXAMPLE:
     {
      "configureBody":{
         "substream":0,
         "temporal":1
      },
      "targetUserId":"targetUserId",
      "userId":"stephen"
     }
    */
function substream(targetUserId, stream) {
    const request =
        JSON.stringify({
            action: "configure",
            userId: id,
            targetUserId: targetUserId,
            configureBody: {
                substream: stream,
            }
        })
    console.log(request);
    socket.send(request);
}
/**
     * {
     *     "userId":"stephen"
     * }
     */
function leave() {
    const request =
        JSON.stringify({
            action: "leave",
            userId: id
        })
    console.log(request);
    socket.send(request);
}
/**
    * MAIN_PARAMETER:
    *     Boolean audio : 是否发送音频
    *     Boolean video : 是否发送视频
    *     Integer pin : 密码
    *     Integer substream : substream（0-2）：数字越大分辨率越高
    *     Integer temporal : temporal（0-2）：数字越大帧率越高
    *     Integer spatial_layer :  <spatial layer to receive (0-1), in case VP9-SVC is enabled; optional>,
    *     Integer temporal_layer : <temporal layers to receive (0-2), in case VP9-SVC is enabled; optional>
    *     Integer bitrate : 最大码率,不设置着为无上限
    *     Boolean restart : 重新协商offer
    *     boolean keyframe :  <true|false, whether we should send this publisher a keyframe request>
    *     boolean record :  <true|false, whether this publisher should be recorded or not; optional>,
    *     String filename :  <if recording, the base path/file to use for the recording files; optional>",
    *     String display : <new display name to use in the room; optional>",
    *     String audio_active_packets : <new audio_active_packets to overwrite in the room one; optional>",
    *     String audio_level_average : <new audio_level_average to overwrite the room one; optional>",
    *     Integer mid : <mid of the m-line to refer to for this configure request; optional>,
    *     boolean send : <true|false, depending on whether the media addressed by the above mid should be relayed or not; optional>,
    * EXAMPLE:
     {
      "configureBody":{
          "audio":true,
          "pin":"123456",
          "request":"configure",
          "video":true
      },
      "jsep":{
          "sdp":"v=0\r\no=- 8960238441194795609...",
          "type":"offer"
      },
      "userId":"stephen"
     }
    */
function sendOffer(offer) {
    const request =
        JSON.stringify({
            action: "offer",
            userId: id,
            jsep: offer
        })
    console.log(request);
    socket.send(request);
}
/**
    * MAIN_PARAMETER:
    *     String ptype : 加入类型publisher or subscriber
    *     String pin : 密码
    *     String display : 加入者身份标识
    *     Long feed : 当作为subscriber加入时候，需要提供feed来订阅音视频
    *     String token :  "<invitation token, in case the room has an ACL; optional>"
    * EXAMPLE:
     {
         "joinBody":{
             "feed":"1604026740488360",
             "pin":"123456"
         },
         "userId":"stephen",
         "targetUserId":"targetUserId"
     }
    */
function joinAndSub(targetUserId) {
    const request =
        JSON.stringify({
            action: "join_sub",
            userId: id,
            targetUserId: targetUserId
        })
    console.log(request);
    socket.send(request);
}
/**
     * MAIN_PARAMETER:
     *     String ptype : 加入类型publisher or subscriber
     *     String pin : 密码
     *     String display : 加入者身份标识
     *     Long feed : 当作为subscriber加入时候，需要提供feed来订阅音视频
     *     String token :  "<invitation token, in case the room has an ACL; optional>"
     * EXAMPLE:
      {
       "joinBody":{
           "ptype":"publisher",
           "pin":"123456",
           "room":999991,
           "display":"stephen"
       },
       "userId":"stephen"
      }
     */
function joinAndPub() {
    const request =
        JSON.stringify({
            action: "join_pub",
            userId: id,
            joinBody: {
                room: room,
                display: id,
                ptype: "publisher"
            }
        })
    console.log(request);
    socket.send(request);
}
function startlive() {
    const request =
        JSON.stringify({
            action: "start_live",
            userId: id
        })
    console.log(request);
    socket.send(request);
}

function stoplive() {
    const request =
        JSON.stringify({
            action: "stop_live",
            userId: id
        })
    console.log(request);
    socket.send(request);
}

function watchLive() {
    const request =
        JSON.stringify({
            action: "watch_live",
            userId: id,
            room: room
        })
    console.log(request);
    socket.send(request);
}
/**
     * {
     *     "userId":"stephen"
     * }
     */
function keepalive() {
    const request =
        JSON.stringify({
            action: "keepalive",
            userId: id,
        })
    console.log(request);
    socket.send(request);
    setTimeout(keepalive, 30000);
}
/**
      {
       "jsep":{
           "sdp":"v=0\r\no=- 3949792525869817657...",
           "type":"answer"
        },
        "userId":"stephen",
        "targetUserId":"Alice"
      }
     */
function start(answer, targetUserId) {
    const request =
        JSON.stringify({
            action: "start",
            userId: id,
            jsep: answer,
            targetUserId: targetUserId
        })
    console.log(request);
    socket.send(request);
}
/**
     {
      candidate":"{
          "candidate":"candidate:547260449 1 udp 2122260223 10.0.2.15 38953 typ host generation 0 ufrag kT2l network-id 3 network-cost 10",
          "pin":"123456",
          "sdpMLineIndex":0,
          "sdpMid":"audio"
      }",
      "userId":"stephen",
      "targetUserId":"targetUserId"
    }
    */
function sendCandidate(targetUserId, candidate) {
    const request =
        JSON.stringify({
            action: "trickle",
            userId: id,
            targetUserId: targetUserId,
            candidate: candidate
        })
    console.log(request);
    socket.send(request);
}
function mungeSdpForSimulcasting(sdp) {
    // Let's munge the SDP to add the attributes for enabling simulcasting
    // (based on https://gist.github.com/ggarber/a19b4c33510028b9c657)
    var lines = sdp.split("\r\n");
    var video = false;
    var ssrc = [-1], ssrc_fid = [-1];
    var cname = null, msid = null, mslabel = null, label = null;
    var insertAt = -1;
    for (let i = 0; i < lines.length; i++) {
        const mline = lines[i].match(/m=(\w+) */);
        if (mline) {
            const medium = mline[1];
            if (medium === "video") {
                // New video m-line: make sure it's the first one
                if (ssrc[0] < 0) {
                    video = true;
                } else {
                    // We're done, let's add the new attributes here
                    insertAt = i;
                    break;
                }
            } else {
                // New non-video m-line: do we have what we were looking for?
                if (ssrc[0] > -1) {
                    // We're done, let's add the new attributes here
                    insertAt = i;
                    break;
                }
            }
            continue;
        }
        if (!video)
            continue;
        var sim = lines[i].match(/a=ssrc-group:SIM (\d+) (\d+) (\d+)/);
        if (sim) {
            Janus.warn("The SDP already contains a SIM attribute, munging will be skipped");
            return sdp;
        }
        var fid = lines[i].match(/a=ssrc-group:FID (\d+) (\d+)/);
        if (fid) {
            ssrc[0] = fid[1];
            ssrc_fid[0] = fid[2];
            lines.splice(i, 1); i--;
            continue;
        }
        if (ssrc[0]) {
            var match = lines[i].match('a=ssrc:' + ssrc[0] + ' cname:(.+)')
            if (match) {
                cname = match[1];
            }
            match = lines[i].match('a=ssrc:' + ssrc[0] + ' msid:(.+)')
            if (match) {
                msid = match[1];
            }
            match = lines[i].match('a=ssrc:' + ssrc[0] + ' mslabel:(.+)')
            if (match) {
                mslabel = match[1];
            }
            match = lines[i].match('a=ssrc:' + ssrc[0] + ' label:(.+)')
            if (match) {
                label = match[1];
            }
            if (lines[i].indexOf('a=ssrc:' + ssrc_fid[0]) === 0) {
                lines.splice(i, 1); i--;
                continue;
            }
            if (lines[i].indexOf('a=ssrc:' + ssrc[0]) === 0) {
                lines.splice(i, 1); i--;
                continue;
            }
        }
        if (lines[i].length == 0) {
            lines.splice(i, 1); i--;
            continue;
        }
    }
    if (ssrc[0] < 0) {
        // Couldn't find a FID attribute, let's just take the first video SSRC we find
        insertAt = -1;
        video = false;
        for (let i = 0; i < lines.length; i++) {
            const mline = lines[i].match(/m=(\w+) */);
            if (mline) {
                const medium = mline[1];
                if (medium === "video") {
                    // New video m-line: make sure it's the first one
                    if (ssrc[0] < 0) {
                        video = true;
                    } else {
                        // We're done, let's add the new attributes here
                        insertAt = i;
                        break;
                    }
                } else {
                    // New non-video m-line: do we have what we were looking for?
                    if (ssrc[0] > -1) {
                        // We're done, let's add the new attributes here
                        insertAt = i;
                        break;
                    }
                }
                continue;
            }
            if (!video)
                continue;
            if (ssrc[0] < 0) {
                var value = lines[i].match(/a=ssrc:(\d+)/);
                if (value) {
                    ssrc[0] = value[1];
                    lines.splice(i, 1); i--;
                    continue;
                }
            } else {
                let match = lines[i].match('a=ssrc:' + ssrc[0] + ' cname:(.+)')
                if (match) {
                    cname = match[1];
                }
                match = lines[i].match('a=ssrc:' + ssrc[0] + ' msid:(.+)')
                if (match) {
                    msid = match[1];
                }
                match = lines[i].match('a=ssrc:' + ssrc[0] + ' mslabel:(.+)')
                if (match) {
                    mslabel = match[1];
                }
                match = lines[i].match('a=ssrc:' + ssrc[0] + ' label:(.+)')
                if (match) {
                    label = match[1];
                }
                if (lines[i].indexOf('a=ssrc:' + ssrc_fid[0]) === 0) {
                    lines.splice(i, 1); i--;
                    continue;
                }
                if (lines[i].indexOf('a=ssrc:' + ssrc[0]) === 0) {
                    lines.splice(i, 1); i--;
                    continue;
                }
            }
            if (lines[i].length === 0) {
                lines.splice(i, 1); i--;
                continue;
            }
        }
    }
    if (ssrc[0] < 0) {
        // Still nothing, let's just return the SDP we were asked to munge
        Janus.warn("Couldn't find the video SSRC, simulcasting NOT enabled");
        return sdp;
    }
    if (insertAt < 0) {
        // Append at the end
        insertAt = lines.length;
    }
    // Generate a couple of SSRCs (for retransmissions too)
    // Note: should we check if there are conflicts, here?
    ssrc[1] = Math.floor(Math.random() * 0xFFFFFFFF);
    ssrc[2] = Math.floor(Math.random() * 0xFFFFFFFF);
    ssrc_fid[1] = Math.floor(Math.random() * 0xFFFFFFFF);
    ssrc_fid[2] = Math.floor(Math.random() * 0xFFFFFFFF);
    // Add attributes to the SDP
    for (var i = 0; i < ssrc.length; i++) {
        if (cname) {
            lines.splice(insertAt, 0, 'a=ssrc:' + ssrc[i] + ' cname:' + cname);
            insertAt++;
        }
        if (msid) {
            lines.splice(insertAt, 0, 'a=ssrc:' + ssrc[i] + ' msid:' + msid);
            insertAt++;
        }
        if (mslabel) {
            lines.splice(insertAt, 0, 'a=ssrc:' + ssrc[i] + ' mslabel:' + mslabel);
            insertAt++;
        }
        if (label) {
            lines.splice(insertAt, 0, 'a=ssrc:' + ssrc[i] + ' label:' + label);
            insertAt++;
        }
        // Add the same info for the retransmission SSRC
        if (cname) {
            lines.splice(insertAt, 0, 'a=ssrc:' + ssrc_fid[i] + ' cname:' + cname);
            insertAt++;
        }
        if (msid) {
            lines.splice(insertAt, 0, 'a=ssrc:' + ssrc_fid[i] + ' msid:' + msid);
            insertAt++;
        }
        if (mslabel) {
            lines.splice(insertAt, 0, 'a=ssrc:' + ssrc_fid[i] + ' mslabel:' + mslabel);
            insertAt++;
        }
        if (label) {
            lines.splice(insertAt, 0, 'a=ssrc:' + ssrc_fid[i] + ' label:' + label);
            insertAt++;
        }
    }
    lines.splice(insertAt, 0, 'a=ssrc-group:FID ' + ssrc[2] + ' ' + ssrc_fid[2]);
    lines.splice(insertAt, 0, 'a=ssrc-group:FID ' + ssrc[1] + ' ' + ssrc_fid[1]);
    lines.splice(insertAt, 0, 'a=ssrc-group:FID ' + ssrc[0] + ' ' + ssrc_fid[0]);
    lines.splice(insertAt, 0, 'a=ssrc-group:SIM ' + ssrc[0] + ' ' + ssrc[1] + ' ' + ssrc[2]);
    sdp = lines.join("\r\n");
    if (!sdp.endsWith("\r\n"))
        sdp += "\r\n";
    return sdp;
}
function uuid2(len, radix) {
    var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
    var uuid = [],
        i;
    radix = radix || chars.length;

    if (len) {
        // Compact form
        for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
    } else {
        // rfc4122, version 4 form
        var r;

        // rfc4122 requires these characters
        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
        uuid[14] = '4';

        // Fill in random data.  At i==19 set the high bits of clock sequence as
        // per rfc4122, sec. 4.1.5
        for (i = 0; i < 36; i++) {
            if (!uuid[i]) {
                r = 0 | Math.random() * 16;
                uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
            }
        }
    }

    return uuid.join('');
}
function getQueryVariable(variable) {
    var query = window.location.search.substring(1);
    var vars = query.split("&");
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split("=");
        if (pair[0] == variable) {
            return pair[1];
        }
    }
    return false;
}